package com.jhgsys.internal.base.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jhgsys.internal.base.dto.BaseProjectDto;
import com.jhgsys.internal.base.entity.BaseArea;
import com.jhgsys.internal.base.entity.BaseProject;
import com.jhgsys.internal.base.entity.BaseProjectArea;
import com.jhgsys.internal.base.entity.BaseProjectUser;
import com.jhgsys.internal.base.mapper.BaseProjectMapper;
import com.jhgsys.internal.base.service.IBaseAreaService;
import com.jhgsys.internal.base.service.IBaseProjectAreaService;
import com.jhgsys.internal.base.service.IBaseProjectService;
import com.jhgsys.internal.base.service.IBaseProjectUserService;
import com.jhgsys.internal.common.entity.FebsConstant;
import com.jhgsys.internal.common.entity.QueryRequest;
import com.jhgsys.internal.common.utils.BeanHelper;
import com.jhgsys.internal.dict.dto.DictItemDto;
import com.jhgsys.internal.dict.entity.DictItem;
import com.jhgsys.internal.dict.service.IDictItemService;
import com.jhgsys.internal.system.entity.Tenant;
import com.jhgsys.internal.system.service.ITenantService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 项目设置 Service实现
 *
 * @author admin
 * @date 2024-07-29 14:19:15
 */
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class BaseProjectServiceImpl extends ServiceImpl<BaseProjectMapper, BaseProject> implements IBaseProjectService {
    @Autowired
    private IBaseProjectUserService baseProjectUserService;

    @Autowired
    private IBaseProjectAreaService baseProjectAreaService;

    @Autowired
    private IBaseAreaService baseAreaService;

    @Autowired
    private ITenantService tenantService;

    @Autowired
    private IDictItemService dictItemService;
    /**
     * 查询（分页）
     * @author admin
     * @date 2024-07-29 14:19:15
     * @param request QueryRequest
     * @param baseProject baseProject
     * @return IPage<BaseProject>
    */
    @Override
    public IPage<BaseProjectDto> findBaseProjects(QueryRequest request, BaseProject baseProject) {
        LambdaQueryWrapper<BaseProject> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BaseProject::getDeletedFlg, FebsConstant.VALID);
        if(StringUtils.isNotBlank(baseProject.getProjectName())){
            queryWrapper.like(BaseProject::getProjectName, baseProject.getProjectName());
        }
        if(StringUtils.isNotBlank(baseProject.getTenantId())){
            queryWrapper.eq(BaseProject::getTenantId, baseProject.getTenantId());
        }
        if(StringUtils.isNotBlank(baseProject.getProjectType())){
            queryWrapper.eq(BaseProject::getProjectType, baseProject.getProjectType());
        }
        if(StringUtils.isNotBlank(baseProject.getStatus())){
            queryWrapper.eq(BaseProject::getStatus, baseProject.getStatus());
        }
        queryWrapper.orderByAsc(BaseProject::getSort);
        Page<BaseProject> page = new Page<>(request.getPageNum(), request.getPageSize());

        IPage<BaseProject> result = this.page(page, queryWrapper);
        IPage<BaseProjectDto> resultPage= new Page<>();

        List<BaseProject> records = result.getRecords();
        List<BaseProjectDto> baseProjectDtoList = BeanHelper.copyWithCollection(records,BaseProjectDto.class);
        if(CollectionUtils.isNotEmpty(baseProjectDtoList)){
            List<String> projectIds = baseProjectDtoList.stream().map(p -> p.getProjectId()).collect(Collectors.toList());
            List<BaseProjectArea> baseProjectAreas = baseProjectAreaService.findByProjectIds(projectIds);
            // 项目类型字典
            DictItem dictItem = new DictItem();
            dictItem.setDictCode("SAFETY_PROJECT_TYPE");
            Map<String, String> projectTypeMap = dictItemService.findDictItems(dictItem).stream().collect(Collectors.toMap(DictItemDto::getItemCode, DictItemDto::getItemName));

            baseProjectDtoList.forEach(p -> {
                List<BaseProjectArea> list =baseProjectAreas.stream().filter(b ->b.getProjectId().equals(p.getProjectId())).collect(Collectors.toList());
                p.setAreaName(list.stream().map(BaseProjectArea::getAreaName).collect(Collectors.joining(",")));
                Tenant tenant = tenantService.findTenantByTenantId(p.getTenantId());
                p.setTenantName(Optional.ofNullable(tenant).map(Tenant::getTenantName).orElse(""));
                p.setProjectTypeName(projectTypeMap.get(p.getProjectType()));
            });

        }
        resultPage.setRecords(baseProjectDtoList);
        resultPage.setTotal(result.getTotal());
        return resultPage;
    }

    /**
     * 查询（所有）
     * @author admin
     * @date 2024-07-29 14:19:15
     * @param baseProject baseProject
     * @return List<BaseProject>
     */
    @Override
    public List<BaseProject> findBaseProjects(BaseProject baseProject) {
	    LambdaQueryWrapper<BaseProject> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BaseProject::getDeletedFlg, FebsConstant.VALID);
        if(StringUtils.isNotBlank(baseProject.getTenantId())){
            queryWrapper.eq(BaseProject::getTenantId, baseProject.getTenantId());
        }
        if(StringUtils.isNotBlank(baseProject.getStatus())){
            queryWrapper.eq(BaseProject::getStatus, baseProject.getStatus());
        }
		return this.baseMapper.selectList(queryWrapper);
    }

    /**
    * 根据ID查询
    * @author admin
    * @date 2024-07-29 14:19:15
    * @param id
    * @return BaseProject
    */
    @Override
    public BaseProjectDto findBaseProjectById(String id){
        BaseProject baseProject =  this.baseMapper.selectById(id);
        BaseProjectDto baseProjectDto = BeanHelper.copyProperties(baseProject, BaseProjectDto.class);
        //查询项目关联人员
        BaseProjectUser baseProjectUser = new BaseProjectUser();
        baseProjectUser.setProjectId(id);
        baseProjectDto.setBaseProjectUserList(baseProjectUserService.findBaseProjectUsers(baseProjectUser));
        //查询项目区域
        setProjectAreas(baseProjectDto);
        return baseProjectDto;
    }

    private void setProjectAreas(BaseProjectDto baseProjectDto) {
        BaseProjectArea baseProjectArea = new BaseProjectArea();
        baseProjectArea.setProjectId(baseProjectDto.getProjectId());
        List<BaseProjectArea> projectAreas = this.baseProjectAreaService.findBaseProjectAreas(baseProjectArea);
        if (CollectionUtils.isNotEmpty(projectAreas)) {
            baseProjectDto.setAreaId(projectAreas.stream().map(r -> r.getAreaId()).collect(Collectors.joining(",")));
            String areaNames =  projectAreas.stream().map(r -> {
                BaseArea baseArea = baseAreaService.findBaseAreaById(r.getAreaId());
                return baseArea.getAreaName();
            }).collect(Collectors.joining(","));
            baseProjectDto.setAreaName(areaNames);
        }
    }

    /**
     * 新增
     * @author admin
     * @date 2024-07-29 14:19:15
     * @param baseProjectDto
     */
    @Override
    @Transactional
    public void createBaseProject(BaseProjectDto baseProjectDto) {
        BaseProject baseProject = BeanHelper.copyProperties(baseProjectDto, BaseProject.class);
        this.save(baseProject);
        baseProjectDto.setProjectId(baseProject.getProjectId());
        //保存项目关联人员信息
        saveBaseProjectUser(baseProjectDto);
        //保存项目区域信息
        saveBaseProjectArea(baseProjectDto);
    }

    /**
     * 修改
     * @author admin
     * @date 2024-07-29 14:19:15
     * @param baseProjectDto
     */
    @Override
    @Transactional
    public void updateBaseProject(BaseProjectDto baseProjectDto) {
        this.updateById(baseProjectDto);
        //删除关联人员
        baseProjectUserService.deleteByProjectIds(baseProjectDto.getProjectId());
        //删除区域信息
        baseProjectAreaService.deleteByProjectIds(baseProjectDto.getProjectId());
        //保存项目关联人员信息
        saveBaseProjectUser(baseProjectDto);
        //保存项目区域信息
        saveBaseProjectArea(baseProjectDto);
    }

    /**
     * 保存项目管理人员
     * @author admin
     * @date 2024-07-29 14:19:15
     * @param baseProjectDto baseProjectDto
     */
    private void saveBaseProjectUser(BaseProjectDto baseProjectDto){
        //保存项目关联人员信息
        if(CollectionUtils.isNotEmpty(baseProjectDto.getBaseProjectUserList())){
            List<BaseProjectUser> baseProjectUserList = baseProjectDto.getBaseProjectUserList().stream()
                    .map(d -> {
                        d.setProjectId(baseProjectDto.getProjectId());
                        d.setCreatedTime(new Date());
                        d.setCreatedBy(baseProjectDto.getCreatedBy());
                        return d;
                    }).collect(Collectors.toList());
            baseProjectUserService.saveBatch(baseProjectUserList);
        }
    }

    /**
     * 保存项目区域
     * @author admin
     * @date 2024-07-29 14:19:15
     * @param baseProjectDto baseProjectDto
     */
    private void saveBaseProjectArea(BaseProjectDto baseProjectDto){
        if(null != baseProjectDto.getAreaId()){
            String[] areaIds = baseProjectDto.getAreaId().split(StringPool.COMMA);
            //保存项目区域信息
            List<BaseProjectArea> baseProjectAreaList = new ArrayList<>();
            Arrays.stream(areaIds).forEach(areaId -> {
                BaseProjectArea bpa = new BaseProjectArea();
                bpa.setCreatedTime(new Date());
                bpa.setCreatedBy(baseProjectDto.getCreatedBy());
                bpa.setProjectId(baseProjectDto.getProjectId());
                bpa.setTenantId(baseProjectDto.getTenantId());
                bpa.setAreaId(areaId);
                bpa.setAreaName(Optional.ofNullable(baseAreaService.findBaseAreaById(areaId)).map(BaseArea::getAreaName).orElse(""));
                baseProjectAreaList.add(bpa);
            });
            baseProjectAreaService.saveBatch(baseProjectAreaList);
        }
    }

    /**
     * 逻辑删除
     * @author admin
     * @date 2024-07-29 14:19:15
     * @param baseProject baseProject
     * @param baseProjectIds baseProjectIds
     */
    @Override
    @Transactional
    public void deleteBaseProject(BaseProject baseProject,String baseProjectIds) {
        List<String> list = Arrays.asList(baseProjectIds.split(StringPool.COMMA));
        this.baseMapper.update(baseProject,new LambdaQueryWrapper<BaseProject>().in(BaseProject::getProjectId,list));
	}

    /**
    * 物理删除
    * @author admin
    * @date 2024-07-29 14:19:15
    * @param baseProjectIds baseProjectIds
    */
    @Override
    @Transactional
    public void physicallyDeleteBaseProject(String baseProjectIds) {
        List<String> list = Arrays.asList(baseProjectIds.split(StringPool.COMMA));
        LambdaQueryWrapper<BaseProject> wapper = new LambdaQueryWrapper<>();
        wapper.in(BaseProject::getProjectId,list);
        this.remove(wapper);
    }

    /**
     * 根据projectIds查询
     * @author admin
     * @date 2024-07-29 14:19:15
     * @param baseProjectIds baseProjectIds
     * @return List<BaseProjectDto>
     */
    @Override
    @Transactional
    public List<BaseProject> findBaseProjectsByIds(List<String> baseProjectIds){
        LambdaQueryWrapper<BaseProject> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(BaseProject::getProjectId,baseProjectIds);
        return this.baseMapper.selectList(wrapper);
    }

}
